#!/usr/bin/python2
#-*- coding:utf-8 -*-

from PyQt4.QtGui import *
from PyQt4.QtCore import *
from PIL import Image
from skimage import data, filters, io
#import matplotlib.pyplot as plt
import os
from tempData import tmpData as td

'''
get picture and cut to pieces
'''
class Div(QObject):
    """docstring for Div"""

    msgemit = pyqtSignal(str)

    # set argvs
    def __init__(self, im):
        super(Div, self).__init__()
        self.im = im # PIL.Image picture
        self.imgry = self.im.convert('L') # greyscale picture
        self.hist = self.im.convert('L').histogram() # grey level
        self.imgbin = None # binary picture after denoise
        self.start = 0

    '''
    division picture function
    frame: mark pixel location
    w: horizontal axis
    h: vertical axis
    cpatcha: pixel of cpatcha
    return four coordinate point of each single cpatcha
    '''
    def divPict(self, frame, w, h, cpatcha = 0):
        print "recv + " + str(td.thresholdL)
        print "--------starting division picture--------"
        pieces = []
        start = 0
        end = 256
        
        # scanning weight and high of the cpatcha
        for i in range(w):
            for j in range(h):
                # if cpatcha different with background, self start = 1
                if frame[i, j] == cpatcha:
                    if self.start == 0:
                        self.start = 1
                        start = i
                    break
            # find cpatcha
            if self.start == 1:
                # j == h - 1, means scan cpatcha done
                if j == (h -1):
                    end = i # mark end location
                    self.start = 0 # horizontal scan done for one piece
                    #if (end - start) > w / 10:
                    piece = [start, 0, end, h] # get a piece
                    
                    # start scan vertical axis
                    # same with horizontal scan
                    for k in range(h):
                        for l in range(w):
                            if frame[l, k] == cpatcha:
                                if self.start == 0:
                                    self.start = 1
                                    start = k
                                break
                        if self.start == 1:
                            if l == (w - 1):
                                self.start = 0
                                end = k
                                piece[1] = start
                                piece[3] = end
                                #if end - start > h / 10:
                                pieces.append(piece)
        
        # assume there are four cpatchas
        len_p = len(pieces)
        dist = [] # distence of begin to end
        for piece in pieces:
                dist.append(piece[2] - piece[0])
        print dist
        sum_d = sum(dist)
        if len(dist) > 0:
            max_d = max(dist)
            index = dist.index(max_d)
        if len_p > 0:
            avg_d = sum_d / len_p
            #print avg_d

        if len_p == 1:
            print "the picture dou ta ma nian zai yi qi"
            print dist
            newlenth = max_d / 4
            alter = pieces[index]
            del pieces[index]
            begin = alter[0] + newlenth
            begin1 = begin + newlenth
            enddd = alter[2] - newlenth
            enddd1 = enddd - newlenth
            first = alter[:]
            first[2] = begin
            second = first[:]
            second[0] = first[2]
            second[2] = begin1
            fourth = alter[:]
            fourth[0] = enddd
            third = fourth[:]
            third[2] = fourth[0]
            third[0] = enddd1
            pieces.insert(0, first)
            pieces.insert(1, second)
            pieces.insert(2, third)
            pieces.insert(3, fourth)
        elif len_p == 2:
            # two situation
            # 2+2
            index_s = dist.index(sum_d - max_d)
            if max_d / 2 < sum_d - max_d:
                print "2+2"
                d1 = max_d / 2
                d2 = (sum_d - max_d) / 2
                alter1 = pieces[index] # long mix
                alter2 = pieces[index_s] # short mix
                del pieces[:] # delete list
                # divide long part
                begin = alter1[0] + d1
                enddd = alter1[2] - d1
                head = alter1[:]
                rear = alter1[:]
                head[2] = begin
                rear[0] = enddd
                pieces.insert(index, head)
                pieces.insert(index + 1, rear)
                # divide short part
                begin = alter2[0] + d2
                enddd = alter2[2] - d2
                head = alter2[:]
                rear = alter2[:]
                head[2] = begin
                rear[0] = enddd
                if index_s > index:
                    pieces.insert(index_s + 1, head)
                    pieces.insert(index_s + 2, rear)
                else:
                    pieces.insert(index_s, head)
                    pieces.insert(index_s + 1, rear)
            # 1+3
            else:
                print "1+3"
                newlenth = ((sum_d - max_d) + max_d / 3) / 2
                alter = pieces[index]
                del pieces[index]
                # three posititon of start 
                begin = alter[0] + newlenth
                enddd = alter[2] - newlenth
                middl = (begin + enddd) / 2
                first = alter[:]
                second = alter[:]
                third = alter[:]
                first[2] = begin
                third[0] = enddd
                second[0] = middl - newlenth / 2
                second[2] = middl + newlenth / 2
                pieces.insert(index, first)
                pieces.insert(index + 1, second)
                pieces.insert(index + 2, third)
        elif len_p == 3:
            print "the picture has benn cut to %s parts:" %str(len_p)
            oth = sum_d - max_d
            if max_d > (sum_d - max_d) :
                newlenth = max_d / 2
                alter = pieces[index]
                del pieces[index]
                #print alter, newlenth
                begin = alter[0] + newlenth
                enddd = alter[2] - newlenth
                #print begin, enddd
                head = alter[:]
                rear = alter[:]
                head[2] = begin
                rear[0] = enddd
                #print head, rear
                pieces.insert(index, head)
                pieces.insert(index + 1, rear)
        else:
            print '4'

        td.list1 = pieces
        print pieces
        return pieces

    '''
    auto denoise function
    use skimage get thresh
    '''
    def denoiseAuto(self):
        table = []
        self.imgry.save('./picture_cache/testgray.png')
        #imageo = io.imread('testcolor.png')
        image = io.imread('./picture_cache/testgray.png', as_gray = True)
        #print image
        thresh = filters.threshold_otsu(image)   #返回一个阈值
        print thresh
        # use plt draw picture
        # dst =(image >= thresh)*1.0   #根据阈值进行分割
        # plt.figure('thresh', figsize = (8, 8))
        # plt.subplot(311)
        # plt.title('original image')
        # plt.imshow(imageo, plt.cm.gray)
        # plt.subplot(312)
        # plt.title('gray image')
        # plt.imshow(image, plt.cm.gray)
        # plt.subplot(313)
        # plt.title('binary image')
        # plt.imshow(dst, plt.cm.gray)
        # plt.show()
        for i in range(256):
            if i <= thresh:
                table.append(0)
            else:
                table.append(1)
        imgPure = self.imgry.point(table, '1')
        print "go to save denoised picture"
        imgPure.save('./picture_cache/test.png')
        print "save success"
        self.imgbin = imgPure
        return thresh

    '''
    denoise function
    not a normal way binary a picture
    '''
    def denoiseHand(self, thresholdL = None, thresholdH = None):
        table = []
        self.imgry.save('./picture_cache/testgray.png')
        # hint function
        #threshold value should decided by some function
        try:
            if thresholdL is None or thresholdH is None:
                # thresholdL = input('门限区间的较小值：\n')
                # thresholdH = input('门限区间的较大值：\n')
                thresholdL = td.thresholdL
                thresholdH = td.thresholdH
            for i in range(256):
                if i >= thresholdL and i <= thresholdH:
                    table.append(0)
                else:
                    table.append(1)
            imgPure = self.imgry.point(table, '1')
            print "save denoised picture"
            if imgPure.save('./picture_cache/test.png'):
                print "save success"
            self.imgbin = imgPure
        except:
            print "denoise failed"
            pass

    def reDenoise():
        pass

    '''
    a main division funciton
    test for divPict function
    2016.6.7
    '''
    def mainDivision(self):
        imgPieces = []
        if self.imgbin is None:
            if td.denoise == 0:
                self.denoiseAuto()
                print "auto"
            else:
                self.denoiseHand()
                print "hand"
        td.denoise = 0
        frame = self.imgbin.load()
        (w, h) = self.imgbin.size
        print w, h
        pieces = self.divPict(frame, w, h)
        i = 1
        for piece in pieces:
            im = self.imgbin.crop(piece)
            print "division %s picture done." %i
            im.save('./picture_cache/DIVISIONED_%s.png'%i)
            i = i + 1
            imgPieces.append(self.imgbin.crop(piece))
        self.imgbin = None
        return imgPieces

def main():
    img = 'testcolor.png'
    im = Image.open(img)
    d = Div(im)
    pieces = d.mainDivision()

if __name__ == '__main__':
    main()